package com.example.springbootdemo.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;

/**
 * @author xuwangqi
 */
@Slf4j
@Configuration
public class WebConfig implements WebMvcConfigurer {

    /**
     * 解决跨域问题 同源是指两个页面具有相同的协议（protocol），主机（host）和端口号（port）
     *
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        /**
         * allowedOrigins：允许设置的请求域名访问我们的跨域资源，可以固定单条或者多条内容，如："http://www.baidu.com"，只有百度可以访问我们的跨域资源。
         * addMapping：配置可以被跨域的路径，可以任意配置，可以具体到直接请求路径。
         * allowedMethods：设置允许的请求方法类型访问该跨域资源服务器，如：POST、GET、PUT、OPTIONS、DELETE等。
         * allowedHeaders：允许所有的请求header访问，可以自定义设置任意请求头信息，如："X-YYYY-TOKEN"
         * allowCredentials： 是否允许请求带有验证信息,用户是否可以发送、处理 cookie
         * maxAge 跨域允许时间
         */
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CommonInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns(
                        //swagger 放行
                        "/v2/api-docs", "/configuration/ui", "/swagger-resources",
                        "/configuration/security", "/swagger-ui.html", "/doc.html",
                        "/webjars/**", "/swagger-resources/configuration/ui",
                        "/swagge‌​r-ui.html", "/swagger-resources/configuration/security",
                        "/test/**",
                        //springSecurity
                        "/login/**",

                        //微信回调
                        "/app/mall/pay/notify",
                        "/app/mall/pay/refunds-notify"

                );
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/backend/login"
                        , "/app/wx/get/info", "/app/wx/login"
                        , "/common/**"
                        , "/app/mall/pay/notify"
                        , "/app/mall/pay/refunds-notify"

                        //springSecurity
                        ,"/login/**"
                        //小程序端不需要登录就能查看的接口放行
                        , "/app/scene/**"
                        , "/app/spot/**"
                        , "/app/scene-strategy/**"
                        , "/app/content/**"
                        , "/app/introduce/**"
                        , "/app/touring-route/**"
                        , "/app/board/list"
                        , "/app/timeline/list"
                        , "/app/mall/coupon",
//                        ,"/","/favicon.ico"
                        //导游模块不需要登录就能查看的端口
                        "/app/converge/info",
                        "/app/converge/travel/info",
                        //商品模块不需要登录就能查看的端口
                        "/app/mall/category/**",
                        "/app/mall/product/**",
                        "/app/mall/product/**",
                        "/app/mall/product/evaluation/list"
                        //swagger 放行
                        , "/v2/api-docs", "/configuration/ui", "/swagger-resources",
                        "/configuration/security", "/swagger-ui.html", "/doc.html",
                        "/webjars/**", "/swagger-resources/configuration/ui",
                        "/swagge‌​r-ui.html", "/swagger-resources/configuration/security"
                );

    }

    /**
     * 统一签名拦截器
     */

    class CommonInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            return true;
            // signature 是将前端请求中的 token+timestamp 按照ASCII码排序 md5加密
//            String signature = request.getHeader("Signature"); //密文
//            String token = request.getHeader("Token");
//            String uid = request.getHeader("uid");
//            String platform = request.getHeader("Platform");
//            String timestamp = request.getHeader("Expires");
//            String randomParam = request.getHeader("X-Request-Id");
//
//            if (StringUtils.isBlank(signature) || StringUtils.isBlank(timestamp) || StringUtils.isBlank(randomParam)) {
//                response(response, ResultEnum.ParameterValidError);
//                return false;
//            }
//
//            long time;
//            try {
//                if (StringUtils.isNotBlank(uid)) {
//                    Long.valueOf(uid);
//                }
//                time = Long.parseLong(timestamp);
//            } catch (Exception e) {
//                log.warn("uid或timestamp不合法");
//                response(response, ResultEnum.ParameterValidError);
//                return false;
//            }
//            //验证时间戳是否过期
//            long currentTime = System.currentTimeMillis() / 1000;
//            if (time > currentTime + TIME_OVER || time < currentTime - TIME_OVER) {
//                log.warn("时间戳过期");
//                response(response, ResultEnum.TimeStampExpired);
//                return false;
//            }
//
//            //将所有参数按照字典序，排序
//            TreeSet<String> treeSet = new TreeSet<>();
//            if (StringUtils.isNotBlank(token)) {
//                treeSet.add(token);
//            }
//            if (StringUtils.isNotBlank(uid)) {
//                treeSet.add(uid);
//            }
//            if (StringUtils.isNotBlank(platform)) {
//                treeSet.add(platform);
//            }
//            treeSet.add(timestamp);
//            treeSet.add(randomParam);
//
//            StringBuilder total = new StringBuilder(); //排序后的字符串
//
//            treeSet.forEach(total::append);
//
//            if (!Md5Util.string2Md5(total.toString()).equalsIgnoreCase(signature)) {
//                log.warn("签名验证失败{}", Md5Util.string2Md5(total.toString()));
//
//                response(response, ResultEnum.SignatureValidError);
//                return false;
//            }
//
//            return true;
        }
//
//        /**
//         * 将异常转为json
//         *
//         * @param response   响应
//         * @param resultEnum 异常
//         * @throws IOException io异常
//         */
//        private void response(HttpServletResponse response, ResultEnum resultEnum) throws IOException {
//            response.setCharacterEncoding("utf-8");
//            response.setContentType("application/json;charset=UTF-8");
//            ServletOutputStream out = response.getOutputStream();
//            out.write(JSON.toJSONBytes(WebResult.fail(resultEnum.getCode(), resultEnum.getMessage())));
//            out.flush();
//            out.close();
//        }

    }

    /**
     * 请求拦截器
     */
    class LoginInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            String uid=request.getHeader("uid");
            LocalDateTime now=LocalDateTime.now();
            log.info("{}在{}访问系统,访问路径{}",uid,now,request.getRequestURI());
            return true;

//            Enumeration<String> params = request.getParameterNames();
//            while (params.hasMoreElements()) {
//                String key = params.nextElement();
//                log.info("params:{}={}", key, request.getParameter(key));
//            }
//            //bool为true 进行下一步
//            //验证token
//            String uid = request.getHeader("uid");
//            String platform = request.getHeader("Platform");
//            String token = request.getHeader("Token");
//
//            // 阻止跨端访问
//            String root = request.getRequestURI().split("//*")[1]; //正则匹配 防止出现"//"的情况
//            if ("backend".equals(root) && !"backmanager".equals(platform)) {
//                response(response, ResultEnum.AccessDenied);
//                return false;
//            } else if ("app".equals(root) && "backmanager".equals(platform)) {
//                response(response, ResultEnum.AccessDenied);
//                return false;
//            }
//
//            if (StringUtils.isBlank(uid) || StringUtils.isBlank(platform) || StringUtils.isBlank(token)) {
//                response(response, ResultEnum.ParameterValidError);
//                return false;
//            }
//
//            String cacheToken = redisService.getToken(uid, platform).split(CommonConst.WX_TOKEN_SEPARATOR)[0];
//            if (StringUtils.isNotBlank(cacheToken) && cacheToken.equals(token)) {
//                return true;
//            } else {
//                log.info("token:{}  redistoken:{}", token, cacheToken);
//                response(response, ResultEnum.AccessTokenError);
//                return false;
//            }
        }

//        /**
//         * 将异常转为json
//         *
//         * @param response   响应
//         * @param resultEnum 异常
//         * @throws IOException io异  常
//         */
//        private void response(HttpServletResponse response, ResultEnum resultEnum) throws IOException {
//            response.setCharacterEncoding("utf-8");
//            response.setContentType("application/json;charset=UTF-8");
//            ServletOutputStream out = response.getOutputStream();
//            out.write(JSON.toJSONBytes(WebResult.fail(resultEnum.getCode(), resultEnum.getMessage())));
//            out.flush();
//            out.close();
//        }

    }

}
